package com.lamda.zhekou.interceptor;

import com.lamda.zhekou.model.User;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Component
public class LoginInterceptor implements HandlerInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoginInterceptor.class);


    /**
     * 运行通过的URL
     */
    private Set<String> allowURls;

    public LoginInterceptor() {
        this.allowURls = new HashSet<>();

        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(LoginInterceptor.class.getClassLoader().getResourceAsStream("mvc/excludeMapping.xml"));
            Element root = document.getRootElement();
            List<Element> childElements = root.elements();

            for (Element childElement : childElements) {
                String path = childElement.attributeValue("path");
                /**
                 * 为了方便判断，对配置的path做简化处理
                 */
                path = path.replace("/", "");
                path = path.replace("*", "");
                this.allowURls.add(path);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
            LOGGER.error("初始化mvc:exclude-mapping失败:" + e.getMessage());
        }
    }


    /**
     * preHandle方法是进行处理器拦截用的，顾名思义，该方法将在Controller处理之前进行调用，SpringMVC中的Interceptor拦截器是链式的，可以同时存在
     * 多个Interceptor，然后SpringMVC会根据声明的前后顺序一个接一个的执行，而且所有的Interceptor中的preHandle方法都会在
     * Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中断的，这种中断方式是令preHandle的返
     * 回值为false，当preHandle的返回值为false的时候整个请求就结束了。
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String uri = request.getRequestURI();

        if (this.isAllow(uri)) {
            return true;
        }

        User user = (User) request.getSession().getAttribute("loginedUser");
        if (user == null) {
            LOGGER.debug("user not login");
            request.getRequestDispatcher("login").forward(request, response);
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }

    private boolean isAllow(String uri) {
        for (String allowURl : allowURls) {
            if (uri.contains(allowURl)) {
                return true;
            }
        }
        return false;
    }


}